home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 October / CD CHIP.ISO / WebServ / server7 / FiltDemo.dpr < prev    next >
Encoding:
Text File  |  1996-10-06  |  12.6 KB  |  304 lines

  1. (***************************************************************************
  2.  
  3.  Name:
  4.    Delphi unit HttpFilt.dpr
  5.  
  6.  Notes:
  7.    This module was built to demonstrate building an ISAPI filter with
  8.    Delphi 2.0. This filter demonstrates all the basic functionality and
  9.    data structures available to ISAPI filters. If compiled, it will create
  10.    httpfilt.dll. You can add this filter to your registry, restart IIS and
  11.    load a page from your IIS server. A log file will be written to
  12.    c:\filtlog.svg showing each event and the filter will modify the data
  13.    written to the HTTP user agent. This filter's purpose in life is to
  14.    demonstrate ISAPI filters--it is very simple, but this should get you
  15.    started with ISAPI filter writing. Best wishes,
  16.  
  17.    Stephen Genusa <steveg@onramp.net> 06/08/96
  18.  
  19.  
  20.  Abstract:
  21.  
  22.    This module contains the types, constants, and functions needed to
  23.    create ISAPI Filter DLLs with Delphi 2.0.
  24.  
  25.    For more information on ISAPI, The Microsoft Internet Information FAQ is
  26.    located at http://rampages.onramp.net/~steveg/iis.html
  27.  
  28.    EyeSAPI, the ISAPI extension debugger/log utility is located at
  29.    http://rampages.onramp.net/~steveg/testisap.zip
  30.  
  31.  
  32.  Changes, fixes, and modifications; in reverse chronological order:
  33.  
  34.   By    Date       Description
  35.   ----- ---------- -----------------------------------------------------------  MWT   7/6/95     Hacked up SVG's work to check filter operation
  36.  
  37.   SVG   06/08/96   Stephen Genusa <steveg@onramp.net>
  38.                    Fixed various structures. Tested most functionality
  39.                    and provided example code to handle each data structure.
  40.  
  41.   JRT   05/05/96   Jonathan R. Taylor <jtaylor@irdg.com>
  42.                    Fixed forward reference problem with the
  43.                    THTTP_FILTER_CONTEXT structure
  44.  
  45.   SVG   05/05/96   Translated From C to Delphi 2.0
  46.                    by Stephen Genusa <steveg@onramp.net>
  47.  
  48.  
  49. ****************************************************************************)
  50.  
  51.  
  52. Library FiltDemo;
  53.  
  54. Uses
  55.   SysUtils,
  56.   Windows;
  57.  
  58. const
  59.  
  60.     HTTP_FILTER_MAJOR          = 1; { major version of this spec }
  61.     HTTP_FILTER_MINOR          = 0; { minor version of this spec }
  62.     SF_MAX_USERNAME            = 257;
  63.     SF_MAX_PASSWORD            = 257;
  64.     SF_MAX_FILTER_DESC_LEN     = 257;
  65.  
  66. { SF_STATUS_TYPE }
  67.     SF_STATUS_TYPE                     = $8000000;  { base value }
  68.     SF_STATUS_REQ_FINISHED             = SF_STATUS_TYPE;
  69.     SF_STATUS_REQ_FINISHED_KEEP_CONN   = SF_STATUS_TYPE + 1;
  70.     SF_STATUS_REQ_NEXT_NOTIFICATION    = SF_STATUS_TYPE + 2;
  71.     SF_STATUS_REQ_HANDLED_NOTIFICATION = SF_STATUS_TYPE + 3;
  72.     SF_STATUS_REQ_ERROR                = SF_STATUS_TYPE + 4;
  73.     SF_STATUS_REQ_READ_NEXT            = SF_STATUS_TYPE + 5;
  74.  
  75.     SF_NOTIFY_SECURE_PORT              = $00000001;
  76.     SF_NOTIFY_NONSECURE_PORT           = $00000002;
  77.     SF_NOTIFY_READ_RAW_DATA            = $00008000;
  78.     SF_NOTIFY_PREPROC_HEADERS          = $00004000;
  79.     SF_NOTIFY_AUTHENTICATION           = $00002000;
  80.     SF_NOTIFY_URL_MAP                  = $00001000;
  81.     SF_NOTIFY_SEND_RAW_DATA            = $00000400;
  82.     SF_NOTIFY_LOG                      = $00000200;
  83.     SF_NOTIFY_END_OF_NET_SESSION       = $00000100;
  84.  
  85.     SF_NOTIFY_ORDER_HIGH               = $00080000;
  86.     SF_NOTIFY_ORDER_MEDIUM             = $00040000;
  87.     SF_NOTIFY_ORDER_LOW                = $00020000;
  88.     SF_NOTIFY_ORDER_DEFAULT            = SF_NOTIFY_ORDER_LOW;
  89.     SF_NOTIFY_ORDER_MASK               = (SF_NOTIFY_ORDER_HIGH or SF_NOTIFY_ORDER_MEDIUM or SF_NOTIFY_ORDER_LOW);
  90.  
  91. type    PVOID = Pointer;
  92.     LPVOID = Pointer;
  93.     PCardinal = ^Cardinal;
  94.  
  95.     SF_REQ_TYPE = (SF_REQ_SEND_RESPONSE_HEADER, SF_REQ_ADD_HEADERS_ON_DENIAL,
  96.                    SF_REQ_SET_NEXT_READ_SIZE, SF_REQ_SET_PROXY_INFO);
  97.  
  98.     Type
  99.       TFuncPlaceHolder = POINTER;
  100.  
  101.     THTTP_FILTER_CONTEXT = record
  102.       cbSize             : DWORD;
  103.       Revision           : DWORD;
  104.       ServerContext      : PVOID;
  105.       ulReserved         : DWORD;
  106.       fIsSecurePort      : BOOL;
  107.       pFilterContext     : PVOID;
  108.       GetServerVariable  : TFuncPlaceHolder; {TGetServerVariable;}
  109.       AddResponseHeaders : TFuncPlaceHolder; {TAddResponseHeaders;}
  110.       WriteClient        : TFuncPlaceHolder; {TWriteClient;}
  111.       AllocMen           : TFuncPlaceHolder; {TAllocMem;}
  112.       ServerSupportFunc  : TFuncPlaceHolder; {TServerSupportFunc;}
  113.     end;
  114.     HTTP_FILTER_CONTEXT = THTTP_FILTER_CONTEXT;
  115.     PHTTP_FILTER_CONTEXT = ^HTTP_FILTER_CONTEXT;
  116.  
  117.  
  118.     TGetServerVariable  = Function(var pfc          : THTTP_FILTER_CONTEXT;
  119.                                        VariableName : PChar;
  120.                                        Buffer       : PChar;
  121.                                        var BuffSize : DWORD) : BOOL;
  122.                                        StdCall;
  123.  
  124.     TAddResponseHeaders = Function(var pfc          : THTTP_FILTER_CONTEXT;
  125.                                        Headers      : PChar;
  126.                                        Reserved     : DWORD) : BOOL;
  127.                                        StdCall;
  128.  
  129.     TWriteClient        = Function(var pfc          : THTTP_FILTER_CONTEXT;
  130.                                        Buffer       : LPVOID;
  131.                                        dwBytes      : LPDWORD;
  132.                                        Reserved     : DWORD) : BOOL;
  133.                                        StdCall;
  134.  
  135.     TAllocMem           = Procedure(var pfc         : THTTP_FILTER_CONTEXT;
  136.                                         cbSize      : DWORD;
  137.                                         dwReserved  : DWORD);
  138.  
  139.     TServerSupportFunc = Function(var  pfc          : THTTP_FILTER_CONTEXT;
  140.                                        sfReq        : SF_REQ_TYPE;
  141.                                        pData        : PVOID;
  142.                                        ul1          : DWORD;
  143.                                        ul2          : DWORD) : BOOL;
  144.                                        StdCall;
  145.  
  146.  
  147.  
  148.     THTTP_FILTER_RAW_DATA = record
  149.       pvInData   : PVOID;
  150.       cbInData   : DWORD;
  151.       cbInBuffer : DWORD;
  152.       dwReserved : DWORD;
  153.     end;
  154.     HTTP_FILTER_RAW_DATA  = THTTP_FILTER_RAW_DATA;
  155.     PHTTP_FILTER_RAW_DATA = ^HTTP_FILTER_RAW_DATA;
  156.  
  157.     TGetHeader = Function(var pfc       : THTTP_FILTER_CONTEXT;
  158.                               lpszName  : PChar;
  159.                               lpvBuffer : LPVOID;
  160.                               lpdwSize  : LPDWORD) : BOOL; StdCall;
  161.  
  162.     TSetHeader = Function(var pfc : THTTP_FILTER_CONTEXT;
  163.                               lpszName  : PChar;
  164.                               lpszValue : PChar) : BOOL; StdCall;
  165.  
  166.     TAddHeader = Function(var pfc : THTTP_FILTER_CONTEXT;
  167.                               lpszName  : PChar;
  168.                               lpszValue : PChar) : BOOL; StdCall;
  169.  
  170.  
  171.  
  172.  
  173.     THTTP_FILTER_PREPROC_HEADERS = record
  174.       GetHeader  : TGetHeader;
  175.       SetHeader  : TSetHeader;
  176.       AddHeader  : TAddHeader;
  177.       dwReserved : DWORD;
  178.     end;
  179.     HTTP_FILTER_PREPROC_HEADERS  = THTTP_FILTER_PREPROC_HEADERS;
  180.     PHTTP_FILTER_PREPROC_HEADERS = ^HTTP_FILTER_PREPROC_HEADERS;
  181.  
  182.  
  183.     THTTP_FILTER_AUTHENT = record
  184.       pszUser        : PChar;
  185.       cbUserBuff     : DWORD;
  186.       pszPassword    : PChar;
  187.       cbPasswordBuff : DWORD;
  188.     end;
  189.     HTTP_FILTER_AUTHENT  = THTTP_FILTER_AUTHENT;
  190.     PHTTP_FILTER_AUTHENT = ^HTTP_FILTER_AUTHENT;
  191.  
  192.  
  193.     THTTP_FILTER_URL_MAP = record
  194.       pszURL : PChar;
  195.       pszPhysicalPath : PChar;
  196.       cbPathBuff : DWORD;
  197.     end;
  198.     HTTP_FILTER_URL_MAP  = THTTP_FILTER_URL_MAP;
  199.     PHTTP_FILTER_URL_MAP = ^HTTP_FILTER_URL_MAP;
  200.  
  201.  
  202.     THTTP_FILTER_LOG = record
  203.       pszClientHostName : PChar;
  204.       pszClientUserName : PChar;
  205.       pszServerName     : PChar;
  206.       pszOperation      : PChar;
  207.       pszTarget         : PChar;
  208.       pszParameters     : PChar;
  209.       dwHttpStatus      : DWORD;
  210.       dwWin32Status     : DWORD;
  211.     end;
  212.     HTTP_FILTER_LOG  = THTTP_FILTER_LOG;
  213.     PHTTP_FILTER_LOG = ^HTTP_FILTER_LOG;
  214.  
  215.  
  216.     THTTP_FILTER_VERSION = record
  217.       dwServerFilterVersion : DWORD;
  218.       dwFilterVersion       : DWORD;
  219.       lpszFilterDesc        : array [0..(SF_MAX_FILTER_DESC_LEN-1)] of Char;
  220.       dwFlags               : DWORD;
  221.     end;
  222.     HTTP_FILTER_VERSION = THTTP_FILTER_VERSION;
  223.     PHTTP_FILTER_VERSION = ^HTTP_FILTER_VERSION;
  224.     TFilter=class     public      procedure AssignContext(var thisFC: HTTP_FILTER_CONTEXT);      function  GetServerVar(varName: String): String;     private      pFC: PHTTP_FILTER_CONTEXT;    end;
  225. procedure TFilter.AssignContext(var thisFC: HTTP_FILTER_CONTEXT);begin  pFC:=@thisFC;end;function  TFilter.GetServerVar(varName: String): String;var  ss: ShortString;
  226.   buf: array[0..255] of char absolute ss;
  227.   len: Integer;
  228.   FNGetServerVariable: TGetServerVariable;
  229. begin
  230.   len:=255;
  231.   @FNGetServerVariable:=pFC^.GetServerVariable;
  232.   if FNGetServerVariable(pFC^, PChar(varName), Pointer(@buf[1]), len ) then
  233.   begin
  234.     ss[0]:=Char(len);
  235.     result:=ss;
  236.   end
  237.   else
  238.     Result:='<UNKNOWN>';
  239. end;function ExpandToken(token, expandedString: String; var buffer: String; var bufferSize: Integer): Integer;var  i: Integer;  newString: String;  sizeDelta: Integer;begin   sizeDelta:=0;   // Keep scanning through the buffer as long   // as we keep finding occurances of the token   repeat     newString:='';     i:=Pos('%'+token+'%', buffer);     if i<>0 then     begin
  240.        // We found the token
  241.        newString:=expandedString;
  242.        buffer:=Copy(buffer, 1, i-1)+newString+Copy(buffer, i+Length(token)+2, bufferSize-i);
  243.  
  244.        // Adjust the buffer size
  245.        bufferSize:=bufferSize+Length(expandedString)-Length(token)-2;
  246.      end   until newString='';   result:=sizeDelta;end;procedure ProcessTokens(var buffer: String; var bufferSize: Integer; filter: TFilter);begin  ExpandToken('TIME',            DateTimeToStr(Now),                      buffer, bufferSize );  ExpandToken('REMOTE_ADDR',     filter.GetServerVar('REMOTE_ADDR'),      buffer, bufferSize );  ExpandToken('REMOTE_USER',     filter.GetServerVar('REMOTE_USER'),      buffer, bufferSize );  ExpandToken('SERVER_NAME',     filter.GetServerVar('SERVER_NAME'),      buffer, bufferSize );  ExpandToken('SERVER_SOFTWARE', filter.GetServerVar('SERVER_SOFTWARE'),  buffer, bufferSize );end;
  247. Function GetFilterVersion(var pVer : HTTP_FILTER_VERSION) : BOOL; export; stdcall;
  248. begin  pVer.dwFilterVersion := MAKELONG(0, 1);
  249.   StrPCopy(pVer.lpszFilterDesc, 'Filter Demo version 0.94');
  250.   pVer.dwFlags := (SF_NOTIFY_URL_MAP OR SF_NOTIFY_SEND_RAW_DATA);
  251.   result := True;
  252. end;
  253.  
  254.  
  255. Function HttpFilterProc(var pfc : HTTP_FILTER_CONTEXT; NotificationType : DWORD; pvNotification : LPVOID) : DWORD; export; stdcall;var  filter: TFilter;   function OnURLMap : DWORD;   var     mapStruct: HTTP_FILTER_URL_MAP;   begin     result := SF_STATUS_REQ_NEXT_NOTIFICATION;     mapStruct:=HTTP_FILTER_URL_MAP(pvNotification^);     //PChar(mapStruct.pszPhysicalPath)[mapStruct.cbPathBuff-1]:=#0;     if (Pos('.HTM', String(mapStruct.pszPhysicalPath))<>0 ) OR (Pos('.htm', String(mapStruct.pszPhysicalPath))<>0 ) then       pfc.pFilterContext:=PVOID(1)     else       pfc.pFilterContext:=PVOID(0);   end;
  256.    // OnSendRawData   function OnSendRawData : DWORD;   var
  257.      rawStruct : PHTTP_FILTER_RAW_DATA;
  258.      s : String;
  259.    begin
  260.      result := SF_STATUS_REQ_NEXT_NOTIFICATION;
  261.  
  262.      if pfc.pFilterContext=nil then
  263.        Exit;
  264.  
  265.      // Cast the pointer. Note we keep it a pointer here
  266.      // locally so that we can return any mods made to the
  267.      // struct (such as length)
  268.      rawStruct := PHTTP_FILTER_RAW_DATA(pvNotification);
  269.  
  270.      PChar(rawStruct.pvInData)[rawStruct.cbInBuffer-1]:=#0;
  271.  
  272.      SetLength(s, 16384);
  273.      StrCopy(PChar(s), rawStruct.pvInData);
  274.  
  275.      // Process the tokens and also make the required
  276.      // adjustments to size
  277.      ProcessTokens(s, rawStruct.cbInData, filter);
  278.  
  279.  
  280.      StrCopy(rawStruct.pvInData, PChar(s));
  281.    end;
  282.  
  283.  
  284.  
  285. begin  result:=SF_STATUS_REQ_NEXT_NOTIFICATION;  //Exit;  try    filter:=TFilter.Create;    filter.AssignContext(pfc);    Case NotificationType of      SF_NOTIFY_URL_MAP:      begin        result:=OnURLMap;      end;      SF_NOTIFY_SEND_RAW_DATA:
  286.       begin        result := OnSendRawData;
  287.       end;
  288.     end;
  289.     filter.Free;
  290.   except
  291.     ;
  292.   end;
  293. end;
  294.  
  295.  
  296.  
  297. exports
  298.   HttpFilterProc,
  299.   GetFilterVersion;
  300.  
  301.  
  302. end.
  303.  
  304.